package com.example.zhanghehe.myapplication.opengl3

import android.content.Context
import android.opengl.GLES30
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import android.util.Log
import java.lang.RuntimeException
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class OpenGl3Render(context: Context):GLSurfaceView.Renderer {
    private var mViewMatrix=FloatArray(16)

    private var mRotationMatrix=FloatArray(16)

    private var mTransX: Float=0f

    private var mTransY: Float = 0f

    private var mAngle=0f

    private var mMVPMatrix=FloatArray(16)

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT or GLES30.GL_DEPTH_BUFFER_BIT)
        GLES30.glEnable(GLES30.GL_DEPTH_TEST)
        Matrix.setLookAtM(mViewMatrix,0,0f,0f,-3f,0f,0f,0f,0f,1.0f,0f)

        Matrix.setIdentityM(mRotationMatrix,0)
        Matrix.translateM(mRotationMatrix,0,mTransX,mTransY,0f)
        Matrix.rotateM(mRotationMatrix,0,mAngle,1.0f,1.0f,1.0f)
        Matrix.multiplyMM(mMVPMatrix,0,mViewMatrix,0,mRotationMatrix,0)

        mCube.draw(mMVPMatrix)
        mAngle+=0.4f
    }



    private var mWidth: Int = 0

    private var mHeight: Int = 0

    private var mProjectionMatrix= FloatArray(16)

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        mWidth=width
        mHeight=height
        GLES30.glViewport(0,0,mWidth,mHeight)
        val apspect=width/height.toFloat()
        Matrix.perspectiveM(mProjectionMatrix,0,53.13f,apspect,Z_NEAR,Z_FAR)
    }

    private lateinit var mCube: Cube

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(0.9f,0.9f,0.9f,0.9f)
        mCube=Cube()
    }

    fun setX(any: Float) {
        mTransX=any
    }

    fun setY(any: Float) {
        mTransY=any
    }

    fun getX(): Float {
        return mTransX
    }

    fun getY(): Float {
        return mTransY
    }


    companion object {
        fun loadShader(type:Int,shaderSrc:String): Int {
            var shader:Int
            var compiled=IntArray(1)

            shader=GLES30.glCreateShader(type)

            if (shader==0) {
                return 0
            }

            GLES30.glShaderSource(shader,shaderSrc)
            GLES30.glCompileShader(shader)
            GLES30.glGetShaderiv(shader,GLES30.GL_COMPILE_STATUS,compiled,0)

            if (compiled[0]==0) {
                Log.e(TAG,"ERROR!!!")
                Log.e(TAG,GLES30.glGetShaderInfoLog(shader))
                GLES30.glDeleteShader(shader)
                return 0
            }
            return shader
        }

        fun checkGlError(glOperation:String){
            var error:Int

            while (GLES30.glGetError()!=GLES30.GL_NO_ERROR){
                error=GLES30.glGetError()
                Log.e(TAG,"glOperation: ${glOperation} ${error}")
                throw RuntimeException("${glOperation} : glErrot ${error}")
            }


        }

        private val TAG=OpenGl3Render::class.java.simpleName
        private val Z_NEAR=1f
        private val Z_FAR=40f
    }

}
